#include "stdafx.h"
#include "gp_Lin.h"
#include "gp_Ax2.h"
#include "gp_Ax1.h"
#include "gp_Pnt.h"
#include "gp_Trsf.h"
#include "gp_Vec.h"
#include "gp_Parab.h"
#include "gp.h"

void gp_Parab::Mirror (const gp_Pnt& P)
{ pos.Mirror (P); }

gp_Parab gp_Parab::Mirrored (const gp_Pnt& P) const
{
	gp_Parab Prb = *this;
	Prb.pos.Mirror (P);
	return Prb;     
}

void gp_Parab::Mirror (const gp_Ax1& A1)
{ pos.Mirror (A1); }

gp_Parab gp_Parab::Mirrored (const gp_Ax1& A1) const
{
	gp_Parab Prb = *this;
	Prb.pos.Mirror (A1);
	return Prb;     
}

void gp_Parab::Mirror (const gp_Ax2& A2)
{ pos.Mirror (A2); }

gp_Parab gp_Parab::Mirrored (const gp_Ax2& A2) const
{
	gp_Parab Prb = *this;
	Prb.pos.Mirror (A2);
	return Prb;     
}
 gp_Parab::gp_Parab () :
focalLength (DBL_MAX)
{ }

 gp_Parab::gp_Parab (const gp_Ax2& A2,
			   const double Focal) :
			   pos(A2),
			   focalLength (Focal)
{ Standard_ConstructionError_Raise_if(Focal < 0.0,""); }

 gp_Parab::gp_Parab (const gp_Ax1& D,
			   const gp_Pnt& F)
{
  gp_Lin Droite(D);
  focalLength = Droite.Distance(F) / 2.;
  gp_Ax1 Ax = Droite.Normal(F).Position();
  gp_Ax1 Ay = Droite.Position();     
  const gp_Dir& DD = Ax.Direction();
  pos = gp_Ax2 (gp_Pnt(F.X() - focalLength * DD.X(),
		       F.Y() - focalLength * DD.Y(),
		       F.Z() - focalLength * DD.Z()),
		Ax.Direction().Crossed(Ay.Direction()),
		Ax.Direction());
}

 void gp_Parab::SetAxis (const gp_Ax1& A1)
{ pos.SetAxis (A1); }

 void gp_Parab::SetFocal (const double Focal)
{ 
  Standard_ConstructionError_Raise_if(Focal < 0.0,"");
  focalLength = Focal;
}

 void gp_Parab::SetLocation (const gp_Pnt& P)
{ pos.SetLocation(P); }

 void gp_Parab::SetPosition (const gp_Ax2& A2)
{ pos = A2; }

 const gp_Ax1& gp_Parab::Axis ()     const
{ return pos.Axis(); }

 gp_Ax1 gp_Parab::Directrix() const
{
  const gp_Pnt& PP = pos.Location  ();
  const gp_Dir& DD = pos.XDirection();
  gp_Pnt P (PP.X() - focalLength * DD.X(),
	    PP.Y() - focalLength * DD.Y(),
	    PP.Z() - focalLength * DD.Z());
  return gp_Ax1 (P, pos.YDirection());
}

   double gp_Parab::Focal() const
{ return focalLength; }

 gp_Pnt gp_Parab::Focus() const
{
  const gp_Pnt& PP = pos.Location  ();
  const gp_Dir& DD = pos.XDirection();
  return gp_Pnt (PP.X() + focalLength * DD.X(),
		 PP.Y() + focalLength * DD.Y(),
		 PP.Z() + focalLength * DD.Z());
}

 const gp_Pnt& gp_Parab::Location () const
{ return pos.Location(); }

 double gp_Parab::Parameter() const
{ return 2.0 * focalLength; }

   const gp_Ax2& gp_Parab::Position() const
{ return pos; }

 gp_Ax1 gp_Parab::XAxis () const
{ return gp_Ax1 (pos.Location(), pos.XDirection()); }

 gp_Ax1 gp_Parab::YAxis () const
{ return gp_Ax1 (pos.Location(), pos.YDirection()); }

 void gp_Parab::Rotate (const gp_Ax1& A1,
			      const double Ang)
{ pos.Rotate (A1, Ang); }

 gp_Parab gp_Parab::Rotated (const gp_Ax1& A1,
				   const double Ang) const
{
  gp_Parab Prb = *this;
  Prb.pos.Rotate (A1, Ang);
  return Prb;     
}

 void gp_Parab::Scale (const gp_Pnt& P,
			     const double S)
{
  focalLength *= S;
  if (focalLength < 0) focalLength = - focalLength;
  pos.Scale (P, S);
}

 gp_Parab gp_Parab::Scaled (const gp_Pnt& P,
				  const double S) const
{
  gp_Parab Prb = *this;
  Prb.focalLength *= S;
  if (Prb.focalLength < 0) Prb.focalLength = - Prb.focalLength;
  Prb.pos.Scale (P, S);
  return Prb;     
}

 void gp_Parab::Transform (const gp_Trsf& T)
{ 
  focalLength *= T.ScaleFactor();
  if (focalLength < 0) focalLength = - focalLength;
  pos.Transform (T); 
}

 gp_Parab gp_Parab::Transformed (const gp_Trsf& T) const
{
  gp_Parab Prb = *this;
  Prb.focalLength *= T.ScaleFactor();
  if (Prb.focalLength < 0) Prb.focalLength = - Prb.focalLength;
  Prb.pos.Transform (T);
  return Prb;     
}

 void gp_Parab::Translate (const gp_Vec& V)
{ pos.Translate (V); }

 gp_Parab gp_Parab::Translated (const gp_Vec& V) const
{
  gp_Parab Prb = *this;
  Prb.pos.Translate (V);
  return Prb;     
}

 void gp_Parab::Translate (const gp_Pnt& P1,
				 const gp_Pnt& P2)
{ pos.Translate (P1, P2); }

 gp_Parab gp_Parab::Translated (const gp_Pnt& P1,
				      const gp_Pnt& P2) const
{
  gp_Parab Prb = *this;
  Prb.pos.Translate (P1, P2);
  return Prb;     
}

